﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using System.Collections.Specialized;
using Noris.Tools.TraceVisualiser.Components;

namespace Noris.Tools.TraceVisualiser.TraceData
{
    /// <summary>
    /// Panel snadného zadání, ikony 64 x 64
    /// </summary>
    internal class SimpleProjectPanelMed : SimpleProjectPanelAbs
    {
        #region Overrides
        public override Image Btn1ImageActive { get { return PicLibrary064.Doc1a_FromFile; } }
        public override Image Btn1ImageInactive { get { return PicLibrary064.Doc1n_FromFile; } }
        public override Image Btn2ImageActive { get { return PicLibrary064.Doc3a_FromFile; } }
        public override Image Btn2ImageInactive { get { return PicLibrary064.Doc3n_FromFile; } }
        public override Image Btn3ImageActive { get { return PicLibrary064.Doc6a_FromFile; } }
        public override Image Btn3ImageInactive { get { return PicLibrary064.Doc6n_FromFile; } }
        public override Image Btn4ImageActive { get { return PicLibrary064.Doc7a_FromFile; } }
        public override Image Btn4ImageInactive { get { return PicLibrary064.Doc7n_FromFile; } }
        public override Image BtnRunImageActive { get { return null; } }
        public override Image BtnRunImageInactive { get { return PicLibrary064.Run_FromFile; } }
        public override Font FileFont { get { return new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); } }
        public override Font HelpFont { get { return new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238))); } }
        public override string InitialDirectory { get; set; }
        public override string DialogFilter { get; set; }
        #endregion
	}
    /// <summary>
    /// 
    /// </summary>
    internal abstract class SimpleProjectPanelAbs : Panel
    {
        #region Konstrukce, fields, interní eventy
        public SimpleProjectPanelAbs()
        {
            this.Initialize();
        }
        protected void Initialize()
        {
            this.Padding = new Padding(6, 6, 6, 6);
            this.Margin = new Padding(3, 3, 3, 3);

            this.HelpObject = new TextBox()
            {
                Multiline = true,
                ReadOnly = true,
                TabStop = false,
                Font = this.HelpFont,
                BackColor = System.Drawing.SystemColors.Info,
                ForeColor = Color.Black,
                Size = new System.Drawing.Size(480, 86),
                ScrollBars = System.Windows.Forms.ScrollBars.Vertical,
                TabIndex = 6
            };

            this.FileText = new HotTextBox()
            {
                Font = this.FileFont,
                Size = new System.Drawing.Size(642, 29),
                HelpControl = this.HelpObject,
                LeaveTextOnExit = true,
                TabIndex = 5
            };

            this.Btn1 = this.CreateBigButton(this.Btn1ImageInactive, this.Btn1ImageActive, "Vybere konkrétní soubor (soubory) pro zobrazení", 0);
            this.Btn2 = this.CreateBigButton(this.Btn2ImageInactive, this.Btn2ImageActive, "Vybere jeden soubor, a zobrazí všechny soubory v adresáři tohoto souboru", 1);
            this.Btn3 = this.CreateBigButton(this.Btn3ImageInactive, this.Btn3ImageActive, "Vybere adresář, a zobrazí soubory z něj a ze všech podadresářů", 2);
            this.Btn4 = this.CreateBigButton(this.Btn4ImageInactive, this.Btn4ImageActive, "Vloží soubory z clipboardu", 3);
            this.BtnRun = this.CreateBigButton(this.BtnRunImageInactive, this.BtnRunImageActive, "Spustí zobrazení vybraných souborů", 4);

            this.Controls.Add(this.HelpObject);
            this.Controls.Add(this.FileText);
            this.Controls.Add(this.Btn1);
            this.Controls.Add(this.Btn2);
            this.Controls.Add(this.Btn3);
            this.Controls.Add(this.Btn4);
            this.Controls.Add(this.BtnRun);

            this.Size = new Size(
                this.Padding.Left + this.Padding.Right + 3 * this.Margin.Left + this.Btn1.Width + this.Btn2.Width + this.Btn3.Width + this.Btn4.Width,
                this.Padding.Top + this.Padding.Bottom + 2 * this.Margin.Top + this.Btn1.Height + this.FileText.Height + this.BtnRun.Height);
            this.MinimumSize = this.Size;

            this.ControlRepositioning();

            this.SizeChanged += new EventHandler(SimpleProjectPanel_SizeChanged);
            this.PaddingChanged += new EventHandler(SimpleProjectPanel_PaddingChanged);

            this.Btn1.Click += new EventHandler(Btn1_Click);
            this.Btn2.Click += new EventHandler(Btn2_Click);
            this.Btn3.Click += new EventHandler(Btn3_Click);
            this.Btn4.Click += new EventHandler(Btn4_Click);
            this.BtnRun.Click += new EventHandler(BtnRun_Click);
        }

        private BigButton CreateBigButton(Image imageN, Image imageA, string helpText, int tabIndex)
        {
            BigButton btn = new BigButton()
            {
                HelpControl = this.HelpObject,
                HelpText = helpText,
                Image = imageN,
                ImageActive = imageA,
                Size = new Size(imageN.Width + 12, imageN.Height + 10),
                TabIndex = tabIndex
            };
            return btn;
        }
        private BigButton Btn1;
        private BigButton Btn2;
        private BigButton Btn3;
        private BigButton Btn4;
        private BigButton BtnRun;
        private HotTextBox FileText;
        private TextBox HelpObject;
        void SimpleProjectPanel_PaddingChanged(object sender, EventArgs e)
        {
            this.ControlRepositioning();
        }
        void SimpleProjectPanel_SizeChanged(object sender, EventArgs e)
        {
            this.ControlRepositioning();
        }
        protected void ControlRepositioning()
        {
            Padding pad = this.Padding;
            Padding mar = this.Margin;
            Point max = new Point(this.ClientSize);

            Point point = new Point(pad.Left, pad.Top);
            ControlRepositioningOne(this.Btn1, ref point, Orientation.Horizontal);
            ControlRepositioningOne(this.Btn2, ref point, Orientation.Horizontal);
            ControlRepositioningOne(this.Btn3, ref point, Orientation.Horizontal);
            this.Btn4.Location = new Point(max.X - pad.Right - this.Btn4.Width, pad.Top);

            this.FileText.Bounds = new Rectangle(pad.Left, this.Btn1.Bottom + mar.Top, max.X - pad.Right - pad.Left, this.FileText.Height);
            point = new Point(pad.Left, this.FileText.Bottom + mar.Top);

            this.BtnRun.Location = new Point(max.X - pad.Right - this.BtnRun.Width, max.Y - pad.Bottom - this.BtnRun.Height);
            this.HelpObject.Bounds = new Rectangle(pad.Left, point.Y, this.BtnRun.Left - mar.Right - pad.Left, max.Y - pad.Bottom - point.Y);
        }
        protected void ControlRepositioningOne(Control control, ref Point point, Orientation orientation)
        {
            control.Location = point;
            if (orientation == Orientation.Horizontal)
                point = new Point(control.Right + this.Margin.Left, control.Top);
            else
                point = new Point(control.Left, control.Top + this.Margin.Top);
        }
        void Btn1_Click(object sender, EventArgs e)
        {
            this.SelectOneFile();
        }
        void Btn2_Click(object sender, EventArgs e)
        {
            this.SelectOneDir();
        }
        void Btn3_Click(object sender, EventArgs e)
        {
            this.SelectSubDir();
        }
        void Btn4_Click(object sender, EventArgs e)
        {
            this.PasteClipboard();
        }
        void BtnRun_Click(object sender, EventArgs e)
        {
            this.OpenDocument();
        }
        protected void ShowText(string text)
        {
            this.HelpObject.Text = text;
        }
        protected void ShowText(string text, Color backColor)
        {
            this.HelpObject.Text = text;
            this.HelpObject.BackColor = backColor;
        }

        private void SetStillActive(BigButton btn)
        {
            this.Btn1.StillActive = Object.ReferenceEquals(this.Btn1, btn);
            this.Btn2.StillActive = Object.ReferenceEquals(this.Btn2, btn);
            this.Btn3.StillActive = Object.ReferenceEquals(this.Btn3, btn);
            this.Btn4.StillActive = Object.ReferenceEquals(this.Btn4, btn);
        }
        #endregion
        #region Výkonné pracovní metody
        public void SelectOneFile()
        {
            string dir = this.InitialDirectory;
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.AddExtension = false;
                ofd.AutoUpgradeEnabled = true;
                ofd.Filter = this.DialogFilter;
                ofd.FilterIndex = 0;
                ofd.CheckFileExists = true;
                ofd.CheckPathExists = true;
                ofd.InitialDirectory = dir;
                ofd.Multiselect = true;
                ofd.RestoreDirectory = true;
                ofd.SupportMultiDottedExtensions = true;
                ofd.Title = "Vyberte soubor(y) pro zobrazení";
                ofd.ValidateNames = false;
                var result = ofd.ShowDialog();
                if (result == DialogResult.OK && ofd.FileNames.Length > 0)
                {
                    List<string> files = new List<string>(ofd.FileNames);
                    this._ShowFiles(files);
                    this.SetStillActive(this.Btn1);
					this._FileSelect = (files.Count == 1 ? FileSelectType.OneFile : FileSelectType.ExplicitFiles);
					this.OnFileSelectChanged(files, this._FileSelect);
                }
            }
        }
        public void SelectOneDir()
        {
            string dir = this.InitialDirectory;
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.AddExtension = false;
                ofd.AutoUpgradeEnabled = true;
                ofd.Filter = this.DialogFilter;
                ofd.FilterIndex = 0;
                ofd.CheckFileExists = true;
                ofd.CheckPathExists = true;
                ofd.InitialDirectory = dir;
                ofd.Multiselect = false;
                ofd.RestoreDirectory = true;
                ofd.SupportMultiDottedExtensions = true;
                ofd.Title = "Vyberte soubor(y) pro zobrazení";
                ofd.ValidateNames = false;
                var result = ofd.ShowDialog();
                if (result == DialogResult.OK && !String.IsNullOrEmpty(ofd.FileName))
                {
                    string path = System.IO.Path.GetDirectoryName(ofd.FileName);
					this._ShowFiles(path, " all files in this directory");
                    this.SetStillActive(this.Btn2);
					this._FileSelect = FileSelectType.OneDirectory;
					this.OnFileSelectChanged(ofd.FileName, this._FileSelect);
                }
            }
        }
        public void SelectSubDir()
        {
            string dir = this.InitialDirectory;
            using (System.Windows.Forms.FolderBrowserDialog fbd = new FolderBrowserDialog())
            {
                fbd.Description = "Vyberte adresář, jehož všechny soubory chcete zobrazit";
                fbd.SelectedPath = dir;
                fbd.ShowNewFolderButton = true;

                DialogResult result = fbd.ShowDialog();
                if (result == DialogResult.OK && fbd.SelectedPath != null)
                {
                    string path = fbd.SelectedPath;
					this._ShowFiles(path, " and all files in all subdirectories");
                    this.SetStillActive(this.Btn3);
					this._FileSelect = FileSelectType.SubDirectory;
					this.OnFileSelectChanged(fbd.SelectedPath, this._FileSelect);
                }
            }
        }
        public void PasteClipboard()
        {
            if (System.Windows.Forms.Clipboard.ContainsFileDropList())
            {
                List<string> files = new List<string>();
                foreach (var file in System.Windows.Forms.Clipboard.GetFileDropList())
                    files.Add(file);
                this._ShowFiles(files);
                this.SetStillActive(this.Btn4);
				this._FileSelect = (files.Count == 1 ? FileSelectType.OneFile : FileSelectType.ExplicitFiles);
				this.OnFileSelectChanged(files, this._FileSelect);
            }
            else
            {
                this.ShowText(@"Ve schránce Windows (Clipboard) není umístěn žádný soubor.
Zkopírujte do schránky soubory (například v Průzkumníku, klávesou Ctrl+C) a zde je vložte tímto tlačítkem.", Color.LightSalmon);
            }
        }
        public void OpenDocument()
        {
            this.OnRun();
        }

		private void _ShowFiles(string path, string info)
		{
			if (path != null)
			{
				this.FileText.Text = path;
				this.FileText.HelpText = path + Environment.NewLine + info;
			}
		}
		private void _ShowFiles(List<string> files)
        {
            files.Sort();

            // Najdu společný začátek textů:
            string common = null;
            if (files.Count > 1)
            {
                foreach (string file in files)
                {
                    string dir = System.IO.Path.GetDirectoryName(file) + "\\";
                    if (common == null)
                        common = dir;

                    int dirLen = dir.Length;
                    int comLen = common.Length;
                    if (common == null)
                        common = dir;
                    else if (dirLen > 0 && comLen > 0)
                    {
                        int len = Math.Min(dirLen, comLen);
                        for (int c = 0; c < len; c++)
                        {
                            if (dir[c] != common[c])
                            {
                                common = common.Substring(0, c);
                                break;
                            }
                        }
                    }
                }
            }

            int comNxt = (common == null ? -1 : common.Length);
            string eol = Environment.NewLine;
            string txt = "";
            string hlp = "";
            if (comNxt > 0)
                hlp = "  " + common + eol;
            foreach (string file in files)
            {
                System.IO.FileInfo fi = new System.IO.FileInfo(file);
                string name = fi.Directory.Name + "\\" + fi.Name;
                txt += (txt.Length == 0 ? "" : "; ") + name;

                if (comNxt > 0)
                    hlp += file.Substring(comNxt) + eol;
                else
                    hlp += file + eol;
            }
            this.FileText.Text = txt;
            this.FileText.HelpText = hlp;
        }
        protected string InitialDirectoryX
        {
            get { return @"D:\Cs2010\TraceVisualiser.data\"; }
        }
        #endregion
        #region Abstract property, určující vzhled
        public abstract Image Btn1ImageActive { get; }
        public abstract Image Btn1ImageInactive { get; }
        public abstract Image Btn2ImageActive { get; }
        public abstract Image Btn2ImageInactive { get; }
        public abstract Image Btn3ImageActive { get; }
        public abstract Image Btn3ImageInactive { get; }
        public abstract Image Btn4ImageActive { get; }
        public abstract Image Btn4ImageInactive { get; }
        public abstract Image BtnRunImageActive { get; }
        public abstract Image BtnRunImageInactive { get; }
        public abstract Font FileFont { get; }
        public abstract Font HelpFont { get; }
        public abstract string InitialDirectory { get; set; }
        public abstract string DialogFilter { get; set; }
        #endregion
		#region Property, metody

		internal void DocumentSet(FileSelectType fileSelect, string filePath, List<string> files)
		{
			this.FileSelect = fileSelect;
			switch (fileSelect)
			{
				case FileSelectType.OneFile:
					this._ShowFiles(filePath, "");
					break;
				case FileSelectType.OneDirectory:
					this._ShowFiles(filePath, " all files in this directory");
					break;
				case FileSelectType.SubDirectory:
					this._ShowFiles(filePath, " and all files in all subdirectories");
					break;
				case FileSelectType.ExplicitFiles:
					this._ShowFiles(files);
					break;
			}
		}
		public FileSelectType FileSelect
		{
			get { return _FileSelect; }
			set { _FileSelectSet(value); }
		}
		private FileSelectType _FileSelect;
		private void _FileSelectSet(FileSelectType fileSelect)
		{
			_FileSelect = fileSelect;
			switch (fileSelect)
			{
				case FileSelectType.OneFile:
					this.SetStillActive(this.Btn1);
					break;
				case FileSelectType.OneDirectory:
					this.SetStillActive(this.Btn2);
					break;
				case FileSelectType.SubDirectory:
					this.SetStillActive(this.Btn3);
					break;
				case FileSelectType.ExplicitFiles:
					this.SetStillActive(this.Btn4);
					break;
			}
		}
		#endregion
        #region Eventy, handlery, args
        /// <summary>
        /// Event při události "Uživatel zadal vstupní soubory"
        /// </summary>
        internal event FileSelectHandler FileSelectChanged;
        protected virtual void OnFileSelectChanged(List<string> files, FileSelectType fileSelect)
        {
            if (this.FileSelectChanged != null)
                this.FileSelectChanged(this, new FileSelectChangeArgs(files, fileSelect));
        }
        protected virtual void OnFileSelectChanged(string file, FileSelectType fileSelect)
        {
            if (this.FileSelectChanged != null)
                this.FileSelectChanged(this, new FileSelectChangeArgs(file, fileSelect));
        }
        /// <summary>
        /// Event při události "Uživatel spustil zobrazení souborů"
        /// </summary>
        internal event EventHandler Run;
        protected virtual void OnRun()
        {
            if (this.Run != null)
                this.Run(this, EventArgs.Empty);
        }
        /// <summary>
        /// Předpis metody pro obsluhu události "Uživatel zadal vstupní soubory"
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        internal delegate void FileSelectHandler(object sender, FileSelectChangeArgs args);
        /// <summary>
        /// Data v události "Uživatel zadal vstupní soubory"
        /// </summary>
        internal class FileSelectChangeArgs : EventArgs
        {
            public FileSelectChangeArgs(string file, FileSelectType fileSelect)
            {
                this.Files = new List<string>();
                this.Files.Add(file);
                this.FileSelect = fileSelect;
            }
            public FileSelectChangeArgs(List<string> files, FileSelectType fileSelect)
            {
                this.Files = files;
                this.FileSelect = fileSelect;
            }
            /// <summary>
            /// Vybrané soubory/zadaný adresář (v prvku [0])
            /// </summary>
            public List<string> Files { get; protected set; }
            /// <summary>
            /// Druh výběru souborů
            /// </summary>
            public FileSelectType FileSelect { get; protected set; }
        }
        /// <summary>
        /// Druh výběru souborů
        /// </summary>
        public enum FileSelectType
        {
            /// <summary>
            /// Nic
            /// </summary>
            None = 0,
            /// <summary>
            /// Jeden soubor
            /// </summary>
            OneFile,
            /// <summary>
            /// Jeden adresář
            /// </summary>
            OneDirectory,
            /// <summary>
            /// Adresář a jeho podadresáře
            /// </summary>
            SubDirectory,
            /// <summary>
            /// Explicitně vyjmenované soubory
            /// </summary>
            ExplicitFiles
        }
        #endregion
    }
}
